package com.noassertions.services;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Locale;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.LockObtainFailedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;



public class LuceneSearcher {

	protected final Log log = LogFactory.getLog(getClass());	
	private MessageSource messageSource;

    @Autowired
    public LuceneSearcher(MessageSource messageSource) throws CorruptIndexException, LockObtainFailedException, IOException {
        this.messageSource = messageSource;
    }
	
	/**
	 * accepts field and query as string, something like: "name", "phillips" and returns either a userid, commentid, or fitid
	 * which of course can be used by the caller to find the complete user, rider, comment, or fit
	 * @param squery
	 * @throws CorruptIndexException
	 * @throws IOException
	 */
	public ArrayList<Integer> search(String field, String query) throws CorruptIndexException, IOException
	{
	    IndexReader reader = IndexReader.open(FSDirectory.open(new File(messageSource.getMessage("luceneIndexDir", null, Locale.getDefault()))), true); // only searching, so read-only=true

	    ArrayList<Integer> listIds = new ArrayList<Integer>();

		//build the query
		IndexSearcher indexSearcher = new IndexSearcher(reader);
		Query termQuery = new WildcardQuery(new Term(field, query));
		
		// get the docs
		TopDocs topDocs = indexSearcher.search(termQuery, null, 10);	
		log.info("Total hits for query: " + termQuery.toString() + " " + topDocs.totalHits);

		// Seems lame that we have to check if it's greater than 0
		if (topDocs.totalHits > 0) {
			// Loop through docs and get list of ids
			ScoreDoc[] scoreDosArray = topDocs.scoreDocs;	
			for (ScoreDoc scoredoc: scoreDosArray) {
				Document doc = indexSearcher.doc(scoredoc.doc);
				if (doc.getField("id") != null) {
					listIds.add(Integer.parseInt(doc.getField("id").stringValue()));
				}
			}
		}
		
		return listIds;
	}
}